/*
 * Copyright (C) 2009 CodeWerkz
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package com.codewerkz.prompty;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

/**
 * Database Adapter for the Presentation Table. CRUD Operations.
 * 
 * @author ChaZ
 */
public class SlidesDbAdapter {
	
	// Database columns.
    public static final String KEY_STITLE = "title";
    public static final String KEY_STEXT = "prompt";
    public static final String KEY_PRESID = "p_id";
    public static final String KEY_ROWID = "_id";
    public static final String KEY_DELAY = "time";

    // Other database related variables.
    private static final String TAG = "SlidesDbAdapter";
    private DatabaseHelper mDbHelper;
    private SQLiteDatabase mDb;
    
    // Database creation SQL Variables.
    private static final String DATABASE_CREATE =
            		"CREATE TABLE slides (_id integer primary key autoincrement, "
                    + "p_id integer not null, title text not null, prompt text not null, time integer);";
    private static final String DATABASE_CREATE2 =
        			"CREATE TABLE presentation (_id integer primary key autoincrement, "
        			+ "name text not null, description text not null, delays integer not null);";

    // Database options (name, table, etc)
    private static final String DATABASE_NAME = "prompty";
    private static final String DATABASE_TABLE = "slides";
    private static final int DATABASE_VERSION = 3;

    private final Context mCtx;

    // ========================================================================
    // 
    // ========================================================================
    /**
     * Database helper class.
     */
    private static class DatabaseHelper extends SQLiteOpenHelper {

        /**
         * Constructor
         * 
         * @param Context Context
         */
        DatabaseHelper(Context context) {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
        }

        /**
         * Runs when the database object is created.
         * 
         * @param db SQLiteDatabase
         * @return void
         */
        @Override
        public void onCreate(SQLiteDatabase db) {
        	Log.w(TAG, "Creating database");
            db.execSQL(DATABASE_CREATE);
            db.execSQL(DATABASE_CREATE2);
        }
        
        /**
         * Runs when the database object is upgraded.
         * 
         * @param db SQLiteDatabase
         * @param oldVersion Integer of version of old database
         * @param newVersion Integer of version of new database
         * @return void
         */
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
                    + newVersion + ", which will destroy all old data");
            db.execSQL("DROP TABLE IF EXISTS slides");
            db.execSQL("DROP TABLE IF EXISTS presentation");
            onCreate(db);
        }
    }

    /**
     * Constructor: Takes the context.
     * 
     * @param ctx Context
     */
    public SlidesDbAdapter(Context ctx) {
        this.mCtx = ctx;
    }

    /**
     * Constructor overload: Open the presentation database. If it cannot be 
     * opened, try to create a new instance of the database. If it cannot be 
     * created, throw an exception to signal failure. 
     */
    public SlidesDbAdapter open() throws SQLException {
        mDbHelper = new DatabaseHelper(mCtx);
        mDb = mDbHelper.getWritableDatabase();
        return this;
    }
    
    /**
     * Closes the database connection.
     * 
     * @return void 
     */
    public void close() {
        mDbHelper.close();
    }

    /**
     * Create a new slide using the title and body and pres ID provided. If the 
    // slide is successfully created return the new rowId for that slide, 
    // otherwise return a -1 to indicate failure.
     * 
     * @param presentation_id Id of presentation.
     * @param slide_title Slide title.
     * @param prompt_text Prompt text.
     * @param delay Time delay in seconds.
     * @return long Row Id of created slide.
     */
    public long createSlide(int presentation_id, String slide_title, String prompt_text, int delay) {
        ContentValues initialValues = new ContentValues();
        initialValues.put(KEY_PRESID, presentation_id);
        initialValues.put(KEY_STITLE, slide_title);
        initialValues.put(KEY_STEXT, prompt_text);
        initialValues.put(KEY_DELAY, delay);
        
        return mDb.insert(DATABASE_TABLE, null, initialValues);
    }

    /**
     * Delete the slide with the given rowId
     * 
     * @param rowId Id of row to delete.
     * @return boolean Returns true if Successful.
     */
    public boolean deleteSlide(long rowId) {
        return mDb.delete(DATABASE_TABLE, KEY_ROWID + "=" + rowId, null) > 0;
    }
    
    /**
     * Delete the slides from a presentation.
     * 
     * @param presID Presentation Id to delete all the slides from.
     * @return boolean Returns true if Successful.
     */
    public boolean deleteSlidesFromPresentation(long presID) {
    	return mDb.delete(DATABASE_TABLE, KEY_PRESID + "=" + presID, null) > 0;
    }
 
    /**
     * Return a Cursor over the list of all slides in the database
     * 
     * @throws SQLException
     * @param presentationID Presentation id to fetch all slides for.
     * @return Cursor Cursor to result.
     */
    public Cursor fetchAllSlides(long presentationID) throws SQLException {

        Cursor mCursor = mDb.query(DATABASE_TABLE, new String[] {KEY_ROWID, KEY_STITLE,
        		KEY_STEXT, KEY_DELAY}, KEY_PRESID + "=" + presentationID, null, null, null, null);
        
        if (mCursor != null) {
        	mCursor.moveToFirst();
        }
        return mCursor;
    }
    
    /**
     * Return a Cursor positioned at the slide that matches the given rowId
     * 
     * @param rowId Row id of slide to fetch.
     * @return Cursor Cursor to result.
     * @throws SQLException 
     */
    public Cursor fetchSlide(long rowId) throws SQLException {

        Cursor mCursor = mDb.query(true, DATABASE_TABLE, new String[] {KEY_ROWID, KEY_PRESID,
        		KEY_STITLE, KEY_STEXT, KEY_DELAY}, KEY_ROWID + "=" + rowId, null,
        		null, null, null, null);
        if (mCursor != null) {
            mCursor.moveToFirst();
        }
        return mCursor;

    }
    
    /**
     * Return a Cursor positioned at the first slide of a given presentation ID
     * 
     * @throws SQLException
     * @param Id of presentation to fetch first slide for.
     * @return Cursor Cursor to result.
     */
    public Cursor fetchFirstSlide (Long rowId) throws SQLException {
    	Cursor mCursor = mDb.query(DATABASE_TABLE, new String[] {KEY_ROWID, KEY_PRESID, KEY_STITLE, KEY_STEXT, KEY_DELAY}, 
    			KEY_PRESID + "=" + rowId, null, null, null, KEY_ROWID + " ASC");
    	
    	if (mCursor != null) {
    		mCursor.moveToFirst();
    	}
    	
    	return mCursor;
    }
    
    /**
     * Update the slide using the details provided. The presentation to 
     * be updated is specified using the rowId, and it is altered to use the 
     * values passed in
     * 
     * @param rowId Row ID of slide.
     * @param slideTitle Slide title.
     * @param slideText Slide text.
     * @param delay Time delay of slide.
     * @return boolean True if successful.
     */
    public boolean updateSlide(long rowId, String slideTitle, String slideText, int delay) {
        ContentValues args = new ContentValues();
        args.put(KEY_STITLE, slideTitle);
        args.put(KEY_STEXT, slideText);
        args.put(KEY_DELAY, delay);
        
        return mDb.update(DATABASE_TABLE, args, KEY_ROWID + "=" + rowId, null) > 0;
    }
}
